using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using HydroDesktop.Database.Tests.MappingTests.DataRepository;
using log4net;
using NUnit.Framework;
using HydroDesktop.ObjectModel;

namespace HydroDesktop.Database.Tests.PerformanceTests
{
    [TestFixture]
    public class ThemePerformanceTest
    {
        static Random random = new Random();
        static ILog perfLog = LogManager.GetLogger("PerfTest");
        private RepositoryManager manager;

        [SetUp]
        public void SetupManager()
        {
             manager = GetManager();
        }
     
        [Test]
        public void SaveTheme()
        {
            CanSaveSeriesWithDataValues2(1000, false, 1, OverwriteOptions.Overwrite);
        }

        //[TestCase(10)]
        //[TestCase(100)]
        //[TestCase(1000)]
        ////[TestCase(10000)]
        //public void SaveThemes2(int runSize)
        //{
        //    int rnd = random.Next(1000);
        //    DateTime startTime = DateTime.Now;
        //    DateTime latstTime = startTime;

        //    perfLog.Info("Starting LoadAndCheckExistingSeries loops:" + runSize);
           

            
        //    perfLog.Info("Initialize Repository Manager" + (DateTime.Now - latstTime).Milliseconds );
        //    latstTime = DateTime.Now;
        //    //a theme is created
        //    Theme theme1 = ThemesTest.CreateTheme();
          
           
        //    perfLog.Info("Initialize theme" + (DateTime.Now - latstTime).Milliseconds );
        //    latstTime = DateTime.Now;

        //    //a series is created and saved to database

        //    List<Series> series = new List<Series>(1000);
        //    for ( int i = 0; i < runSize; i++ )
        //    {
        //        series.Add( DataSeriesTest.CreateSeries(random.Next()));
                
        //    }
        //    perfLog.Info("Initialize theme" + (DateTime.Now - latstTime).Milliseconds );
        //    latstTime = DateTime.Now;

        //    manager.BeginTransaction();
        //    foreach (Series s in series){
        //        manager.SaveSeries(s, theme1, OverwriteOptions.Copy);
        //    }
        //    manager.Commit();

        //    ////a new identical series is created in-memory
        //    //Series series2 = HydroDesktop.Database.Tests.DataSeriesTest.CreateSeries(rnd);
        //    //series2.Site = series1.Site;
        //    //series2.Variable = series1.Variable;
        //    //series2.Method = series1.Method;
        //    //series2.QualityControlLevel = series1.QualityControlLevel;
        //    //series2.Source = series1.Source;

        //    //Series existing = manager.SeriesDAO.CheckForExisting(series2);

        //    //Assert.AreEqual(series2.Id, 0, "series2 should be unsaved (id==0)");
        //    //Assert.AreNotEqual(existing.Id, 0, "the 'existing' series should be retrieved from db (id > 0)");

        //    //the 'existing' series should be equal to 'series1' previously saved
        //    //Assert.AreEqual(existing, series1, "The 'existing' series should be equal to 'series1' previously saved.");
        //}

        [Test]
        public void CanSaveSeriesWithDataValuesNoQualifiers()
        {
            CanSaveSeriesWithDataValues2(1000, false, 1, OverwriteOptions.Copy);
        }
        [Test]
        public void CanSaveSeriesWithDataValuesWithQualiers()
        {
            CanSaveSeriesWithDataValues2(1000, false, 1, OverwriteOptions.Copy);
        }

        [Test]
        public void SaveThemes()
        {
            CanSaveSeriesWithDataValues2(1000, false, 10, OverwriteOptions.Copy);
        }

        [Test, Combinatorial]
        public void CanSaveSeriesWithDataValues2([Values(100, 1000, 10000, 100000, 5000000)] int runSize, [Values(true, false)] bool withQualifiers, [Values(1, 10, 50)] int numberOfThemes, OverwriteOptions overrightOptions)
        {
            List<Theme> themes = new List<Theme>(numberOfThemes);

            int rnd = random.Next(1000);

            DateTime startTime = DateTime.Now;
            DateTime latstTime = startTime;


            perfLog.Info("Starting CanSaveSeriesWithDataValues2 datavalues:" + runSize + " Qualifiers=" +withQualifiers);


            perfLog.Info("Initialize Repository Manager" + (DateTime.Now - latstTime).Milliseconds);
            latstTime = DateTime.Now;

            //a series with default site, variable, method and quality control is created..
            Series series1 = DataSeriesTest.CreateSeries(rnd);
            perfLog.Info("created series" + (DateTime.Now - latstTime).Milliseconds);
            latstTime = DateTime.Now;
            for (int i = runSize; i < 0; i-- )
            {
                series1.AddDataValue(DateTime.Now.Date.AddMinutes(-runSize), rnd);
            
                if (withQualifiers){
                    series1.DataValueList[0].Qualifier = QualifiersTest.CreateQualifier();
                }
            }
            perfLog.Info("created " + runSize +"DataValues. " + (DateTime.Now - latstTime).Milliseconds);
            latstTime = DateTime.Now;

            string siteName = series1.Site.Name;

            //Theme myTheme = new Theme("My Theme", "the testing theme number 1.");
            for (int i = 0; i < numberOfThemes; i++ )
            {
                themes.Add(createTheme(random.Next())); 
            }

            perfLog.Info("created " + runSize + "DataValues. " + (DateTime.Now - latstTime).Milliseconds);
            latstTime = DateTime.Now;
            manager.SaveSeries(series1, themes[0], overrightOptions);

            perfLog.Info("Saved series with " + runSize + "DataValues. " + (DateTime.Now - latstTime).Milliseconds);
            latstTime = DateTime.Now;
            //Series fromDB = manager.SeriesDAO.FindUnique("Site.Name", siteName);

            //Assert.AreEqual(fromDB.ValueCount, 2, "the retrieved series should have two data values.");
        }


        static Theme createTheme(int id)
        {
            return new Theme("My Theme", "the testing theme number " + id + ".");
        }

        static RepositoryManager GetManager()
        {
            return Config.RepositoryManager;
        }

    }
}